package com.example.tccdemo.service;

import com.example.tccdemo.db163.dao.AccountAMapper;
import com.example.tccdemo.db163.dao.PaymentMsgMapper;
import com.example.tccdemo.db163.model.AccountA;
import com.example.tccdemo.db163.model.PaymentMsg;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.client.producer.SendStatus;
import org.apache.rocketmq.common.message.Message;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;

/**
 * @author caryguan
 * @version V1.0
 * @Package com.example.tccdemo.service
 * @date 2020/10/15 20:35
 */

@Service //这个主要操作放本地消息表的数据库
public class PaymentService {

    @Resource
    private AccountAMapper accountAMapper;

    @Resource
    private PaymentMsgMapper paymentMsgMapper;

    @Resource
    private DefaultMQProducer producer;

    /**
     * 支付接口
     *
     * @param userId
     * @param orderId
     * @param amount
     * @return 返回1用户不存在 2.余额不足 0代表成功
     */

    @Transactional(transactionManager = "tm163")
    public int payment(int userId, int orderId, BigDecimal amount) {
        //根据用户Id找出用户账户表
        AccountA accountA = accountAMapper.selectByPrimaryKey(userId);

        if (accountA == null) {
            return 1;
        }

        //如果扣减的钱大于余额的话提示余额不足
        if (accountA.getBalance().compareTo(amount) < 0) {
            return 2;
        }

        //注意用decimal类要注意计算都是用API
        accountA.setBalance(accountA.getBalance().subtract(amount));
        accountAMapper.updateByPrimaryKey(accountA);

        //创建支付消息
        PaymentMsg paymentMsg = new PaymentMsg();
        paymentMsg.setOrderId(orderId);
        paymentMsg.setStatus(0);//未发送
        paymentMsg.setFailureCount(0);//失败次数
        paymentMsg.setCreateTime(new Date());
        paymentMsg.setCreateUser(userId);
        paymentMsg.setUpdateTime(new Date());
        paymentMsg.setUpdateUser(userId);
        paymentMsgMapper.insertSelective(paymentMsg);

        //返回0代表成功
        return 0;
    }

    @Transactional(transactionManager = "tm163", rollbackFor = Exception.class)
    public int paymentMQ(int userId, int orderId, BigDecimal amount) throws Exception {
        /**
         * 扣减消息余额
         */
        //根据用户Id找出用户账户表
        AccountA accountA = accountAMapper.selectByPrimaryKey(userId);

        if (accountA == null) {
            return 1;
        }

        //如果扣减的钱大于余额的话提示余额不足
        if (accountA.getBalance().compareTo(amount) < 0) {
            return 2;
        }

        //注意用decimal类要注意计算都是用API
        accountA.setBalance(accountA.getBalance().subtract(amount));
        accountAMapper.updateByPrimaryKey(accountA);

        /**
         * 将支付消息放入消息队列
         */
        //创建支付消息
        Message message = new Message();
        //设置消息主题(分类),并且要和消费端一致
        message.setTopic("payment");
        message.setKeys(orderId + "");
        message.setBody("订单已支付".getBytes());
        try {
            SendResult result = producer.send(message);
            if (result.getSendStatus() == SendStatus.SEND_OK) {
                return 0;
            } else {
                throw new Exception("消息发送失败!");
            }
        } catch (Exception e) {
            e.printStackTrace();
            //一定要抛出,如果不抛出的话,方法就正常结束了,事务注解就不会起作用
            throw e;
        }

        //返回0代表成功
    }
}